﻿using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.OpenApi.Models;
using StarsAdmin.Core.App;
using StarsAdmin.Core.Attributes;
using StarsAdmin.Core.Cache;
using StarsAdmin.Core.Consts;
using StarsAdmin.Core.DB.Entities;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace StarsAdmin.Web.Core.Filter
{
    /// <summary>
    /// 添加获取所有Api接口
    /// </summary>
    public class ApiDocumentFilter : IDocumentFilter
    {
        public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            var tags = swaggerDoc.Tags;
            var paths = swaggerDoc.Paths;

            var controllerApiList = new List<ApiEntity>();
            var actionApiList = new List<ApiEntity>();
            // 获取所有控制器
            foreach (OpenApiTag tag in tags)
            {
                var name = tag.Name;
                var label = tag.Description;
                ApiEntity addApiInput = new ApiEntity()
                {
                    Name = name,
                    Path = name,
                    Label = label,
                };
                controllerApiList.Add(addApiInput);
            }
            // 获取所有action
            var sort = controllerApiList.Count + 1;
            foreach (var item in paths)
            {
                var label = item.Value.Operations.Values.FirstOrDefault()?.Summary;
                var path = item.Key;
                ApiEntity addApiInput = new ApiEntity()
                {
                    Label = label,
                    Path = path,
                    Sort = sort,
                };
                actionApiList.Add(addApiInput);
                sort++;
            }
            // 获取所有action注释
            foreach (var apiDescription in context.ApiDescriptions)
            {
                var order = 0;
                // 获取当前ApiDescription的所有的ActionDescriptor转换为ControllerActionDescriptor
                var actionDescriptor = apiDescription.ActionDescriptor as ControllerActionDescriptor;
                // 获得所有ActionDescriptor的属性标记，并筛选出OrderAttribute属性标记
                var objOrderAttribute = actionDescriptor.EndpointMetadata.FirstOrDefault(x => x is OrderAttribute);
                // 获得OrderAttribute的值
                if (objOrderAttribute != null)
                {
                    var orderAttribute = objOrderAttribute as OrderAttribute;
                    order = orderAttribute.Value;
                }

                var methods = apiDescription.HttpMethod;
                var actionPath = apiDescription.RelativePath;
                var actionName = actionDescriptor.ActionName;
                var controllerName = actionDescriptor.ControllerName;

                // 设置控制器排序
                var controllerApi = controllerApiList.Where(e => e.Name == controllerName).FirstOrDefault();
                if (controllerApi?.Sort != default)
                {
                    controllerApi.Sort = order;
                }
                // 设置action参数
                var actionApi = actionApiList.Where(e => e.Path == $"/{actionPath}").FirstOrDefault();
                if (actionApi?.Path != null)
                {
                    actionApi.Label = $"{controllerApi.Label} / {actionApi.Label}";
                    actionApi.HttpMethod = methods;
                    actionApi.Path = actionPath;
                    actionApi.Name = actionName;
                }
                controllerApi.Children.Add(actionApi);
            }

            var _cache = AppHelper.GetService<ICacheService>();
            if (_cache != null)
            {
                _cache.Set(CacheKeyConst.ApiDocumentKey, controllerApiList.OrderBy(e => e.Sort));
            }
        }
    }
}